/*
 ============================================================================
 Name        : PARALLEL-ROSA-ANALYSER.c
 Author      : Raúl Pardo Jiménez
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lib/SyntacticTreeLibrary.h"
#include "lib/HashTableLTS.h"
#include "lib/OperationalSemanticsChooser.h"

typedef struct {
	int bucketState[1000]; //0 Empty, 1 Written
	char idsToBeProcessed[1000][1000];
	int numberOfIds;
} nodesToProcess;

void insertId(nodesToProcess *list, char *id) {
	//If the position is not occupied
	if (list->bucketState[list->numberOfIds] == 0) {
		strcpy(list->idsToBeProcessed[list->numberOfIds], id);
		list->bucketState[list->numberOfIds] = 1;
//		list->numberOfIds++;
		return;
		//Or if it tries to store in a occupied position
	} else if (list->bucketState[list->numberOfIds] == 1) {
		list->numberOfIds++;
		insertId(list, id);
		return;
	}
}

char *getId(nodesToProcess *list) {

	if (list->numberOfIds >= 0) {
		char *result = (char *) malloc(sizeof(char) * 10000);

		if (list->bucketState[list->numberOfIds] == 0) {
			list->numberOfIds--;
			return getId(list);
		} else if (list->bucketState[list->numberOfIds] == 1) {
			strcpy(result, list->idsToBeProcessed[list->numberOfIds]);
			list->bucketState[list->numberOfIds] = 0;
			strcpy(list->idsToBeProcessed[list->numberOfIds], "");
//		list->numberOfIds--;
			return result;
		} else {
			printf("Error: trying to get a new Id\n");
			return NULL ;
		}
	}
	return NULL ;
}

char* getStringFromInput() {
	/*
	 * Copied from the internet, In particular this link http://bit.ly/O1UQ2J
	 */
	unsigned int len_max = 128;
	unsigned int current_size = 0;

	char *pStr = malloc(len_max);
	current_size = len_max;

	printf("\nEnter a String value:");

	if (pStr != NULL ) {
		int c = EOF;
		unsigned int i = 0;
		//accept user input until hit enter or end of file
		while ((c = getchar()) != '\n' && c != EOF) {
			pStr[i++] = (char) c;

			//if i reached maximize size then realloc size
			if (i == current_size) {
				current_size = i + len_max;
				pStr = realloc(pStr, current_size);
			}
		}

		pStr[i] = '\0';

	}
	return pStr;
}

int main(void) {

	printf("/***********************TESBEDS***********************/ \n");
	/*
	 * Generating a syntactic tree from the mathematical
	 * expression
	 */
	printf(
			"Generating a syntactic tree from the mathematical expression\n");
	char *id;
	id = getStringFromInput();
	Node *newTree = (Node *) malloc(sizeof(Node));
	sT_getSyntacticTree(newTree, id, "0");
//	sT_printout(newTree);printf("\n");

	hashTableLTS *hashTable;
	hashTable = hLTS_create();

	stateLTS *initialState = (stateLTS *) malloc(sizeof(stateLTS));

	initialState->id = "0";
	initialState->node = (Node *) malloc(sizeof(Node));
	sT_getSubTree(newTree, initialState->node, "0");
	initialState->state = 1; //DONE
	initialState->numberOfTransitions = 0;

	processingOutput *output = (processingOutput *) malloc(
			sizeof(processingOutput));

	nodesToProcess *list = (nodesToProcess *) malloc(sizeof(nodesToProcess));
	list->numberOfIds = 0;
	int j;
	for (j = 0; j < 1000; j++) {
		list->bucketState[j] = 0;
	}



	hLTS_insert(hashTable, initialState);
	insertId(list, "0");
	do {
//		printf("\n");
		int n = hLTS_getNumberOfNodes(hashTable);

		char *nId = getId(list);
		if (nId != NULL ) {
			initialState = hLTS_getNode(hashTable, nId);
		}
		printf("Id: %s\n",initialState->id);
		oS_processingNode(initialState, output);

		int i;
		for (i = 0; i < output->numOfStates; i++) {
			stateLTS newN;
			newN = output->obtainedStates[i];
			hLTS_insert(hashTable, &newN);
			insertId(list, output->obtainedStates[i].id);
		}

	} while (list->numberOfIds > 0);

	hLTS_printHashTableState(hashTable);

	printf("\nTests have been rightly complete!\n");
	return EXIT_SUCCESS;
}

